package cn.edu.scau.cmi.yanghongyu.util;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.HashSet;
import java.util.function.Consumer;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.google.gson.Gson;

public class GetChildren implements ApplicationContextAware{
	private ApplicationContext applicationContext;
	private HashSet<String> keyWords;
	private StringBuilder stringBuilder = new StringBuilder();
	public GetChildren() {
		setApplicationContext(WebApplicationContextUtils.getRequiredWebApplicationContext(ContextLoader.getCurrentWebApplicationContext().getServletContext()));
		keyWords = new HashSet<String>();
	}
	
	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		this.applicationContext = applicationContext;
	}
	
	
	public ApplicationContext getApplicationContext() {
		return applicationContext;
	}
	
	
	/**
	 * 
	 * @param parent					父节点Id
	 * @param type						父节点类名
	 * @param pageNumber				第几页，从1开始
	 * @param paginationSize					每页数据数量
	 * @param keywords					要筛选出的字段，默认值为["id", "name", "description"]
	 * @return							类似下面的json数据	
	 * {
	 * 		"page" : {
	 * 			"pageNumber" : 1,
	 * 			"paginationSize" : 10,
	 * 			"beginPagination" : 1,
	 * 			"totalPaginations" : 3,
	 * 			"totalRecords" : 23
	 * 		},
	 * 		"data" : [
	 * 			{
	 * 				"id" : ,
	 *	  			"name" : "北京",
	 *	  			"description" : "介绍"
	 * 			},
	 * 			{
	 * 				"id" : ,
	 *	  			"name" : "南京",
	 *	  			"description" : "介绍"
	 * 			},
	 * 			{
	 * 				"id" : ,
	 *	  			"name" : "东京",
	 *	  			"description" : "介绍"
	 * 			}，
	 * 			{
	 * 				"id" : ,
	 *	  			"name" : "西京",
	 *	  			"description" : "介绍"
	 * 			}
	 * 		]
	 * }
	 * 
	 * 
	 * @throws ClassNotFoundException
	 * @throws NoSuchMethodException
	 * @throws SecurityException
	 * @throws IllegalAccessException
	 * @throws IllegalArgumentException
	 * @throws InvocationTargetException
	 */
	public String getChildren(Integer parent, String type, Integer pageNumber, Integer paginationSize, String ...keywords ) throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		keyWords.clear();
		if(keywords.length == 0) {
			keyWords.add("id");
			keyWords.add("name");
			keyWords.add("description");
		} else {
			for (String str : keywords) {
				keyWords.add(str);
			}
		}
		
		stringBuilder.delete(0, stringBuilder.length());
		Class<?> typeServiceName = Class.forName("cn.edu.scau.cmi.ema.service." + type + "Service"); // TODO 这里可以修改，包名不一定是这个
		Object bean = applicationContext.getBean(type + "Service", typeServiceName);
		Class<? extends Object> classService = bean.getClass();
		if(pageNumber <= 0) pageNumber = 1;
		if(paginationSize <= 0) paginationSize = 10;
		
		Method countTypesByName = classService.getMethod("count" + type + "sByParent", Integer.class);
		int totalRecords = (int) countTypesByName.invoke(bean, parent);
		int totalPaginations = totalRecords % paginationSize == 0 ? totalRecords / paginationSize : totalRecords / paginationSize + 1;
		if(pageNumber > totalPaginations) pageNumber = totalPaginations;
		Method findTypesByParent = classService.getMethod("find" + type + "sByParent", Integer.class, Integer.class, Integer.class);
		Object methodResult = findTypesByParent.invoke(bean, parent, pageNumber, paginationSize);
		
		stringBuilder.append("{");
		stringBuilder.append("\"page\" :");
		stringBuilder.append("{");
		stringBuilder.append("\"pageNumber\":");
		stringBuilder.append(pageNumber);
		stringBuilder.append(",");
		stringBuilder.append("\"paginationSize\":");
		stringBuilder.append(paginationSize);
		stringBuilder.append(",");
		stringBuilder.append("\"beginPagination\":");
		stringBuilder.append(1);
		stringBuilder.append(",");
		stringBuilder.append("\"totalPaginations\":");
		stringBuilder.append(totalPaginations);
		stringBuilder.append(",");
		stringBuilder.append("\"totalRecords\":");
		stringBuilder.append(totalRecords);
		stringBuilder.append("},");
		stringBuilder.append("\"data\":");
		stringBuilder.append("[");
		toJsonByKeyWords(methodResult);
		if (stringBuilder.charAt(stringBuilder.length()-1) != '[') stringBuilder.setLength(stringBuilder.length()-1);
		stringBuilder.append("]");
		stringBuilder.append("}");
		
//		AddressService tempService = (AddressService) applicationContext.getBean("AddressService");
//		List<Address4Adapter> addresssByParent = tempService.findAddresssByParent(parent, pageNumber, paginationSize);
//		toJsonByKeyWords(addresssByParent);
		return stringBuilder.toString();
	}

	private void toJsonByKeyWords(Object object) {
		if (!(object instanceof Collection<?>)) return;
		Collection<Object> objects = (Collection<Object>) object;
		objects.forEach(new Consumer<Object>() {
			@Override
			public void accept(Object obj) {
				Field[] fields = obj.getClass().getDeclaredFields();
	            Field.setAccessible(fields, true);
	            boolean fit = false; // 为false时，说明没有符合的字段
	            stringBuilder.append("{");
	            for (Field field : fields) {
	            	String fieldName = field.getName();
	            	if (!keyWords.contains(fieldName)) continue;
	            	fit = true;
	            	Object fieldValue = null;
					try {
						fieldValue = field.get(obj);
					} catch (IllegalArgumentException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (IllegalAccessException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
	            	stringBuilder.append("\"").append(fieldName).append("\"").append(":").append(new Gson().toJson(fieldValue))
                    .append(",");
				}
	            stringBuilder.setLength(stringBuilder.length()-1);
	            if (fit) stringBuilder.append("},");
			}
		});
	}
//	public static void printAllBeans() {
//		String[] beans = GetChildren.getApplicationContext()
//				.getBeanDefinitionNames();
//		for (String beanName : beans) {
//			Class<?> beanType = GetChildren.getApplicationContext()
//					.getType(beanName);
//			System.out.println("BeanName:" + beanName);
//			System.out.println("Bean的类型：" + beanType);
//			System.out.println("Bean所在的包：" + beanType.getPackage());
//			System.out.println("Bean：" + GetChildren.getApplicationContext().getBean(
//					beanName));
//		}
//	}
}
